/*******************************************************************************
 * Copyright (c) 2000, 2005 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package com.architexa.org.eclipse.gef;

import com.architexa.org.eclipse.draw2d.geometry.Point;

import java.util.Collection;


/**
 * A helper returned from a {@link com.architexa.org.eclipse.gef.GraphicalEditPart}. Certain
 * <code>DragTrackers</code> tools and native drop listeners will make use of autoexpose
 * helpers to reveal any potential drop areas that are currently not visible to the user.
 * An example of this is scrolling a container to reveal unexposed area. Another example
 * is a bunch of stacked containers in a "tab folder" arrangement, whever hovering over a
 * tab should switch which container is on top.
 * <P>
 * Autoexpose helpers are obtained from editparts that are target of whatever operation is
 * being performed. If the target provides no helper, its parent chain is traversed
 * looking for helpers. A helper will be obtained under conditions deemed appropriate by
 * the caller, such as when the mouse has paused for some amount of time in the current
 * location.
 * <P>
 * An autoexpose helper may be short-lived or long-running.  A short-lived helper would be
 * something like the example described above when a "page" is being flipped. A
 * long-running example is auto-scrolling. A helper requests to remains active by
 * returning <code>true</code> from its {@link #step(Point)} method for as long as
 * necessary. An active helper can remain active even as the mouse is moving. The client
 * may stop calling <code>step(Point)</code> at any time, even if <code>false</code> was
 * never returned, such as when the user releases the mouse.
 * 
 * @author hudsonr
 */
public interface AutoexposeHelper {

/**
 * Returns <code>true</code> if the specified location is interesting to the helper. This
 * method gets called as part of the search for an AutoexposeHelper.  The helper should
 * do something if it returns <code>true</code>, or it may wait for {@link #step(Point)}
 * to be called later.
 * @param where the mouse's current location in the viewer
 * @return <code>true</code> if the location is interesting
 */
boolean detect(Point where);

/**
 * Performs the autoexpose and returns a hint indicating that the helper would like to
 * remain active. The client will continue to call step() for as long as it
 * previously returned <code>true</code>, and the conditions are deemed appropriate to
 * continue the autoexpose process.
 * <P>
 * The client may stop calling this method at any time, even if the previous invocation
 * returned <code>true</code>. The return value is a hint.
 * @param where the current location of the mouse in the viewer
 * @return a hint indicating whether this helper should continue to be invoked
 */
boolean step(Point where);

/**
 * Used with EditPartViewers to find the AutoexposeHelper at a Point. Clients can
 * instantiate the search, call 
 * {@link EditPartViewer#findObjectAtExcluding(Point,Collection, 
 * 												EditPartViewer.Conditional)}, 
 * and then check the {@link #result} field.
 */
class Search implements EditPartViewer.Conditional {
	/**
	 * Constructs a new Search at a point on the viewer.
	 * @param pt the mouse location
	 */
	public Search(Point pt) {
		where = pt;
	}
	
	/**
	 * the result of the search.
	 */
	private Point where;
	public AutoexposeHelper result;
	public boolean evaluate(EditPart editpart) {
		result = (AutoexposeHelper)editpart.getAdapter(AutoexposeHelper.class);
		if (result != null && result.detect(where))
			return true;
		result = null;
		return false;
	}
}

}
